"""
音频录制与处理模块

提供音频录制、播放和处理功能
"""

import os
import pyaudio
import wave
from typing import Dict, Any, List, Optional

class AudioRecorder:
    """音频录制和处理工具类"""
    
    def __init__(self, config: Dict[str, Any] = None, debug: bool = False):
        """
        初始化音频录制器
        
        Args:
            config: 音频配置
            debug: 是否启用调试模式
        """
        self.debug = debug
        config = config or {}
        
        # 音频参数
        self.CHUNK = config.get("chunk", 1024)
        self.FORMAT = getattr(pyaudio, f"paInt{config.get('format', 16)}", pyaudio.paInt16)
        self.CHANNELS = config.get("channels", 1)
        self.RATE = config.get("rate", 16000)
        self.RECORD_SECONDS = config.get("record_seconds", 5)
        
        # 临时目录
        self.temp_dir = config.get("temp_dir", "temp")
        if not os.path.exists(self.temp_dir):
            os.makedirs(self.temp_dir)
            
        if self.debug:
            print(f"调试信息 - 音频配置: {config}")
    
    def record_audio(self, output_path: Optional[str] = None) -> str:
        """
        录制音频并保存到文件
        
        Args:
            output_path: 输出文件路径，如果为None则使用默认路径
            
        Returns:
            保存的音频文件路径
        """
        if output_path is None:
            output_path = os.path.join(self.temp_dir, "recording.wav")
            
        p = pyaudio.PyAudio()
        
        if self.debug:
            print(f"调试信息 - 开始录音，将保存到: {output_path}")
            print(f"调试信息 - 音频参数: 采样率={self.RATE}, 通道数={self.CHANNELS}")
            
        print("开始录音...")
        try:
            stream = p.open(format=self.FORMAT,
                            channels=self.CHANNELS,
                            rate=self.RATE,
                            input=True,
                            frames_per_buffer=self.CHUNK)
            
            frames: List[bytes] = []
            for i in range(0, int(self.RATE / self.CHUNK * self.RECORD_SECONDS)):
                data = stream.read(self.CHUNK, exception_on_overflow=False)
                frames.append(data)
                
            print("录音结束")
            
            stream.stop_stream()
            stream.close()
            
        except Exception as e:
            print(f"录音过程中发生错误: {e}")
            if p:
                p.terminate()
            return ""
            
        p.terminate()
        
        # 保存录音
        try:
            self._save_audio(frames, output_path, p)
            if self.debug:
                print(f"调试信息 - 录音已保存到: {output_path}")
        except Exception as e:
            print(f"保存录音时发生错误: {e}")
            return ""
            
        return output_path
    
    def _save_audio(self, frames: List[bytes], output_path: str, p_audio: pyaudio.PyAudio) -> None:
        """
        将录制的音频保存为文件
        
        Args:
            frames: 音频帧列表
            output_path: 输出文件路径
            p_audio: PyAudio实例
        """
        os.makedirs(os.path.dirname(os.path.abspath(output_path)), exist_ok=True)
        
        wf = wave.open(output_path, 'wb')
        wf.setnchannels(self.CHANNELS)
        wf.setsampwidth(p_audio.get_sample_size(self.FORMAT))
        wf.setframerate(self.RATE)
        wf.writeframes(b''.join(frames))
        wf.close()
    
    def play_audio(self, file_path: str) -> bool:
        """
        播放音频文件
        
        Args:
            file_path: 音频文件路径
            
        Returns:
            是否成功播放
        """
        if not os.path.exists(file_path):
            print(f"错误：音频文件 {file_path} 不存在")
            return False
            
        if self.debug:
            print(f"调试信息 - 播放音频: {file_path}")
            
        try:
            wf = wave.open(file_path, 'rb')
            p = pyaudio.PyAudio()
            
            stream = p.open(format=p.get_format_from_width(wf.getsampwidth()),
                           channels=wf.getnchannels(),
                           rate=wf.getframerate(),
                           output=True)
            
            data = wf.readframes(self.CHUNK)
            while data:
                stream.write(data)
                data = wf.readframes(self.CHUNK)
                
            stream.stop_stream()
            stream.close()
            p.terminate()
            return True
            
        except Exception as e:
            print(f"播放音频时发生错误: {e}")
            return False
    
    def validate_audio_file(self, file_path: str) -> Optional[str]:
        """
        验证音频文件是否可用
        
        Args:
            file_path: 音频文件路径
            
        Returns:
            有效的音频文件路径或None
        """
        if not os.path.exists(file_path):
            print(f"错误：文件 {file_path} 不存在")
            return None
            
        if not file_path.endswith('.wav'):
            print("错误：只支持 .wav 格式的音频文件")
            return None
        
        if self.debug:
            print(f"调试信息 - 验证音频文件: {file_path}")
            try:
                with wave.open(file_path, 'rb') as wf:
                    print(f"调试信息 - 音频文件信息: 通道数={wf.getnchannels()}, "
                          f"采样宽度={wf.getsampwidth()}, 采样率={wf.getframerate()}, "
                          f"帧数={wf.getnframes()}")
            except Exception as e:
                print(f"调试信息 - 无法读取音频文件信息: {e}")
                
        return file_path 